﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;

using Infrastructure.Core.IOC;
using Infrastructure.Utility;

using SMG.Application.DTO.Migration;
using SMG.ServiceContract.Migration;
using SMG.Monitor.Domain.Models;
using SMG.Application.DTO.Program;
using SMG.ServiceContract.Program;
using Infrastructure.Core.Loging;

namespace SMG.Monitor.Domain.Processor
{
    /// <summary>
    /// 图文表单处理类
    /// </summary>
    public class PlayProcessor : IProcessor
    {
        /// <summary>
        /// 节目单迁移服务
        /// </summary>
        IPlayMoveService playMoveService = ServiceLocator.Instance.Resolve<IPlayMoveService>();
        /// <summary>
        /// 节目单服务
        /// </summary>
        IProgramBillService billService = ServiceLocator.Instance.Resolve<IProgramBillService>();
        /// <summary>
        /// 频道服务
        /// </summary>
        IChannelService channelService = ServiceLocator.Instance.Resolve<IChannelService>();
        /// <summary>
        /// 日志服务
        /// </summary>
        ILogger logServer = LogService.GetInstance(LogType.Text);
        /// <summary>
        /// 频道列表
        /// </summary>
        List<ChannelDto> channels;

        //外网资源服务器地址
        String OutsideStoreServer = ConfigurationManager.AppSettings["OutsideStoreServer"];
        //中间存储服务器地址
        String TranslateStoreServer = ConfigurationManager.AppSettings["TranslateStoreServer"];

        public PlayProcessor() {
            channels = channelService.QueryChannelAll().ToList();
            if (channels == null) channels = new List<ChannelDto>();
        }

        public void Preprocess(PlayRecordDto playRecord)
        {
            try
            {
                if (String.IsNullOrEmpty(playRecord.PlayContent))
                {
                    throw new Exception("节目单内容为空");
                }
                var broadcast = SerializeUtility.XmlDeserialize<BroadcastList>(playRecord.PlayContent);
                if (broadcast == null)
                {
                    throw new Exception(String.Format("节目单内容结构异常:{0}", playRecord.PlayContent));
                }

                var result = false;
                if (playRecord.TaskStatus == 0)
                {
                    result = GenFirstMoveTask(broadcast, playRecord);
                    if (result) playRecord.TaskStatus = 1;
                }
                else if (playRecord.TaskStatus == 1 && playRecord.MoveStatus == 1)
                {
                    result = GenSecondMoveTask(playRecord);
                    if (result) playRecord.TaskStatus = 2;
                }
            }
            catch (Exception ex)
            {
                playRecord.TaskStatus = 9;
                //logServer.Info("FirstTaskDispatcher.Dispatching.ExceptionIn", ex.Message);
            }
            finally
            {
                //设置节目单并解锁
                playMoveService.UnLockPlayRecord(playRecord);
            }
        }

        /// <summary>
        /// 生成一级任务
        /// </summary>
        /// <param name="playRecord"></param>
        /// <returns></returns>
        private Boolean GenFirstMoveTask(BroadcastList broadcast, PlayRecordDto playRecord)
        {
            playRecord.ChannelId = broadcast.ChannelId;
            playRecord.PlayDate = broadcast.PlayDate;
            playRecord.PlayVersion = broadcast.Version;

            #region 生成一级任务和节目单信息

            //主任务
            var taskDto = new FirstMoveTaskDto()
            {
                Code = "",
                PlayID = playRecord.ID,
                ChannelId = broadcast.ChannelId,
                ListId = broadcast.ListId,
                SourceServer = OutsideStoreServer,
                TargetServer = TranslateStoreServer,
                Status = 0,
                CreateTime = DateTime.Now,
                UpdateTime = DateTime.Now
            };
            //任务详细列表
            var taskDetails = FirstTaskDetailMapping(broadcast);
            taskDetails.ForEach(detail => detail.PlayID = playRecord.ID);

            //节目单版本记录
            var billVersionDto = ProgramVersionMapping(broadcast);
            //节目详细列表
            var billDtos = ProgramBillMapping(broadcast);

            //添加一级迁移任务
            var result = playMoveService.AddFirstMoveTask(taskDto, taskDetails);
            if (result)
            {
                //保存节目单信息
                billService.InsertBatchProgramBill(billVersionDto, billDtos);
            }

            #endregion

            return result;
        }
        /// <summary>
        /// 生成二级任务
        /// </summary>
        /// <param name="playRecord"></param>
        /// <returns></returns>
        private Boolean GenSecondMoveTask(PlayRecordDto playRecord) {
            var firstTaskDetailStates = playMoveService.QueryFirstTaskDetailState(playRecord.ID);
            if (firstTaskDetailStates == null || !firstTaskDetailStates.Any())
                throw new Exception("没有找到节目单对应的一级迁移任务状态明细数据");

            var channel = channels.FirstOrDefault(c => c.ChannelId == playRecord.ChannelId);

            #region 生成二级任务

            //主任务
            var taskDto = new SecondMoveTaskDto()
            {
                Code = "",
                PlayID = playRecord.ID,
                ChannelId = playRecord.ChannelId,
                ListId = firstTaskDetailStates.FirstOrDefault().ListId,
                SourceServer = TranslateStoreServer,
                TargetServer = channel == null ? "" : channel.FolderMediaMaster,
                Status = 0,
                CreateTime = DateTime.Now,
                UpdateTime = DateTime.Now
            };
            //任务详细列表
            var taskDetails = new List<SecondMoveTaskDetailDto>();
            foreach (var firstDetail in firstTaskDetailStates)
            {
                var detail = new SecondMoveTaskDetailDto()
                {
                    PlayID = firstDetail.PlayID,
                    ChannelId = firstDetail.ChannelId,
                    ListId = firstDetail.ListId,
                    ItemId = firstDetail.ItemId,
                    FileName = firstDetail.FileName,
                    FileType = firstDetail.FileType,
                    IsHD = firstDetail.IsHD,
                    SourcePath = firstDetail.TargetPath,
                    TargetPath = firstDetail.TargetPath,
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now
                };
                taskDetails.Add(detail);
            }

            //添加二级迁移任务
            var result = playMoveService.AddSecondMoveTask(taskDto, taskDetails);

            #endregion

            return result;
        }

        #region Private Methods

        BillVersionRecordDto ProgramVersionMapping(BroadcastList broadcast)
        {
            if (broadcast == null) return null;
            return new BillVersionRecordDto()
            {
                ListId = broadcast.ListId,
                ChannelId = broadcast.ChannelId,
                PlayDate = broadcast.PlayDate,
                BillName = broadcast.ListName,
                BillVersion = broadcast.Version,
                Subtitles = broadcast.Subtitles,
                CreateTime = broadcast.CreateTime,
                Creator = broadcast.Creator,
                EditTime = broadcast.EditTime,
                Editor = broadcast.Editor,
                AuditTime = broadcast.AuditTime,
                Auditor = broadcast.Auditor,
            };
        }

        List<ProgramBillDto> ProgramBillMapping(BroadcastList broadcast)
        {
            if (broadcast == null) return null;

            var bills = new List<ProgramBillDto>();
            if (broadcast.ListItem != null && broadcast.ListItem.Any())
            {
                foreach (var item in broadcast.ListItem)
                {
                    var billDto = new ProgramBillDto()
                    {
                        #region 节目单主信息
                        ListId = broadcast.ListId,
                        ChannelId = broadcast.ChannelId,
                        PlayDate = broadcast.PlayDate,
                        BillName = broadcast.ListName,
                        BillVersion = broadcast.Version,
                        Subtitles = broadcast.Subtitles,
                        CreateTime = broadcast.CreateTime,
                        Creator = broadcast.Creator,
                        EditTime = broadcast.EditTime,
                        Editor = broadcast.Editor,
                        AuditTime = broadcast.AuditTime,
                        Auditor = broadcast.Auditor,
                        #endregion

                        #region 节目单详细信息
                        ItemId = item.ItemId,
                        ItemIndex = item.ItemIndex,
                        ProgramTitle = item.ProgramTitle,
                        PlayTime = item.PlayTime,
                        ItemType = item.ItemType,
                        ProgramId = item.ProgramId,
                        InPoint = item.InPoint,
                        OutPoint = item.OutPoint,
                        Duration = item.Duration,
                        TapeId = item.TapeId,
                        TapeType = item.TapeType,
                        PlayDeviceId = item.PlayDeviceId,
                        StudioName = item.StudioName,
                        PlayPattern = item.PlayPattern,
                        ProgramSource = item.ProgramSource,
                        TapeInPoint = item.TapeInPoint,
                        TapeOutPoint = item.TapeOutPoint,
                        PlayMode = item.PlayMode,
                        ProgramType = item.ProgramType,
                        ReplaySymbol = item.ReplaySymbol,
                        ProgramLibMode = item.ProgramLibMode,
                        Afd = item.Afd,
                        IsHD = item.IsHD,
                        Notation = item.Notation,
                        CueTone = item.CueTone
                        #endregion
                    };
                    bills.Add(billDto);
                }
            }
            return bills;
        }

        List<FirstMoveTaskDetailDto> FirstTaskDetailMapping(BroadcastList broadcast)
        {
            if (broadcast == null) return null;

            //Regex reg = new Regex("*.*");
            var taskDetails = new List<FirstMoveTaskDetailDto>();
            if (broadcast.ListItem != null && broadcast.ListItem.Any())
            {
                foreach (var list in broadcast.ListItem)
                {
                    if (list.CG == null || list.CG.Item == null || !list.CG.Item.Any())
                        continue;

                    foreach (var item in list.CG.Item)
                    {
                        if (item.Elements == null || !item.Elements.Any())
                            continue;
                        foreach (var elem in item.Elements)
                        {
                            if (elem.ExtendAttribute != null)
                            {
                                if (elem.ExtendAttribute.AttributeValue.IndexOf(".") > 0
                                    && elem.ExtendAttribute.AttributeType.ToLower() == "file")
                                {
                                    var fileName = "";
                                    if (elem.ExtendAttribute.AttributeValue.IndexOf("/") >= 0) fileName = elem.ExtendAttribute.AttributeValue.Substring(elem.ExtendAttribute.AttributeValue.LastIndexOf("/") + 1);
                                    else if (elem.ExtendAttribute.AttributeValue.IndexOf(@"\") >= 0) fileName = elem.ExtendAttribute.AttributeValue.Substring(elem.ExtendAttribute.AttributeValue.LastIndexOf(@"\") + 1);
                                    var detail = new FirstMoveTaskDetailDto()
                                    {
                                        ChannelId = broadcast.ChannelId,
                                        ListId = broadcast.ListId,
                                        ItemId = list.ItemId,
                                        FileName = fileName,
                                        FileType = elem.ExtendAttribute.AttributeType,
                                        IsHD = Int32.Parse(item.IsHD),
                                        SourcePath = elem.ExtendAttribute.AttributeValue,
                                        TargetPath = elem.ExtendAttribute.AttributeValue,
                                        CreateTime = DateTime.Now,
                                        UpdateTime = DateTime.Now
                                    };
                                    taskDetails.Add(detail);
                                }
                            }
                        }
                    }

                }
            }
            return taskDetails;

        }

        #endregion

    }
}
